﻿using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using SharppiFlowEditor.models;
using SharppiFlowEditor.views;

namespace SharppiFlowEditor.controllers
{
    public class EditPropertyController : AbstractController
    {

        /*
        * The delegate for graph select events.
        */
        public delegate void GraphSelectEventHandler(object sender, FlowChartEventArgs e);

        /*
         * The event for graph select events.
         */
        public event GraphSelectEventHandler GraphObjectSelected;
        private AbstractNode moving = null;
        private int offsx, offsy;

        public EditPropertyController(AppView appView, AppModel appModel)
        {
            Model = appModel;
            View = appView;

            View.DocPropView.SaveButton.Click += new EventHandler(DocSaveButton_Click);
            View.ConnPropView.SaveButton.Click += new EventHandler(ConnSaveButton_Click);
            View.NodePropView.SaveButton.Click += new EventHandler(NodeSaveButton_Click);
        }


        void NodeSaveButton_Click(object sender, EventArgs e)
        {
            //throw new NotImplementedException();
            if (View.document.SelectedObject != null)
            {
                AbstractNode an = null;
                                
                int newx = View.NodePropView.NodeLocation.X;
                int newy = View.NodePropView.NodeLocation.Y;
                string newTitle = View.NodePropView.Title;         

                string help = "";
                int newType = 0;
                switch (View.document.SelectedObject.GetType().ToString())
                {
                    case "SharppiFlowEditor.models.EndNode":
                        an = (EndNode)View.document.SelectedObject;
                        help = "End Node";
                        break;
                    case "SharppiFlowEditor.models.ConditionalNode":
                        an = (ConditionalNode)View.document.SelectedObject;
                        help = "Conditional Node";
                        break;
                    case "SharppiFlowEditor.models.ActionNode":
                        an = (ActionNode)View.document.SelectedObject;
                        help = "Action node";
                        break;
                }

                switch (View.NodePropView.NodeType)
                {
                    case "Action Node":
                        newType = 2;
                        break;
                    case "Conditional Node":
                        newType = 3;
                        break;
                    case "End Node":
                        newType = 1;
                        break;
                }

                if (View.NodePropView.NodeType != ""  && View.NodePropView.NodeType != help)
                {
                    Model.DeleteNode(View.document.GraphDocument, an);
                    an = Model.createAbstractNodeRENAMETHISMETHODLATER(View.document.GraphDocument,
                                                                    newx,
                                                                    newy,
                                                                    10, 10,
                                                                    newTitle,
                                                                    newType);
                    View.document.SelectedObject = an;
                }
                else
                {
                    an.Title = newTitle;
                    an.setBoundingRectLocation(newx, newy);  
                }                                
            }
            View.document.Invalidate();
            View.document.Update();
        }


        void ConnSaveButton_Click(object sender, EventArgs e)
        {
            Connector c = (Connector)View.document.SelectedObject;

            if (View.ConnPropView.node1Title != c.Node1.Title)
            {
                AbstractNode an = c.Node1;
                c.Node1 = c.Node2;
                c.Node2 = an;
            }
            c.Text = View.ConnPropView.ConnText;
            View.document.Invalidate();
            View.document.Update();
        }


        void DocSaveButton_Click(object sender, EventArgs e)
        {
            Model.ChangeDocumentSize(View.DocPropView.SelectedDocument, new Size(Convert.ToInt32(View.DocPropView.DocWidth), Convert.ToInt32(View.DocPropView.DocHeight)));
        }

        override public void ViewMouseDown(object sender, MouseEventArgs e)
        {
            scrollOffset = View.document.ViewScrollPosition;
            int xPosition = e.X - scrollOffset.X;
            int yPosition = e.Y - scrollOffset.Y;

            //AbstractNode an = View.document.GetNode(xPosition, yPosition);
            //moving = an;
            //Connector c = View.document.getConnectorAtPoint(new PointF(xPosition, yPosition));


            if (e.Button == MouseButtons.Left)
            {
                if (View.document.GetNode(xPosition, yPosition) != null)
                {
                    //an.Title = View.ShowMyDialogBox();
                    AbstractNode an = View.document.GetNode(xPosition, yPosition);
                    moving = an;
                    offsx = (int)((e.X - scrollOffset.X) / zoomValue) - moving.getBoundingRect().X;
                    offsy = (int)((e.Y - scrollOffset.Y) / zoomValue) - moving.getBoundingRect().Y;
                    GraphObjectSelected(this, new FlowChartEventArgs(an, false));

                    View.document.SelectedObject = an;
                    View.document.Invalidate();
                    View.document.Update();
                }

                else if (View.document.getConnectorAtPoint(new PointF(xPosition, yPosition)) != null)
                {
                    //c.Text = View.ShowMyDialogBox();
                    Connector c = View.document.getConnectorAtPoint(new PointF(xPosition, yPosition));
                    GraphObjectSelected(this, new FlowChartEventArgs(c, false));

                    View.document.SelectedObject = c;
                    c.Color = Color.Green;
                    View.document.Invalidate();
                    View.document.Update();
                }
                else
                {
                    GraphObjectSelected(this, new FlowChartEventArgs());
                    View.document.Invalidate();
                    View.document.Update();
                }
            }
            else if (View.document.GetNode(xPosition, yPosition) != null) // right click
            {
                //an.Title = View.ShowMyDialogBox();
                AbstractNode an = View.document.GetNode(xPosition, yPosition);
                int previousType = an.Type;
                if (previousType == 3)
                {
                    previousType = 0;
                }
                int x = an.getBoundingRect().X;
                int y = an.getBoundingRect().Y;
                Model.DeleteNode(View.document.GraphDocument, an);

                an = Model.createAbstractNodeRENAMETHISMETHODLATER(View.document.GraphDocument, x, y, 20, 20, "default", previousType + 1);
                
                               
            }

            View.document.Invalidate();
            View.document.Update();
        }

        override public void ViewMouseMove(object sender, MouseEventArgs e)
        {
            scrollOffset = View.document.ViewScrollPosition;
            zoomValue = View.document.ZoomSize;

            if (moving != null)
            {
                if (View.document.GraphDocument.SnapToGridState.Equals(true))
                {
                    int x = (int)((e.X - scrollOffset.X) / zoomValue) - offsx;
                    int y = (int)((e.Y - scrollOffset.Y) / zoomValue) - offsy;

                    Model.MoveNode(View.document.GraphDocument, moving, View.document.GraphDocument.SnapX(x), View.document.GraphDocument.SnapY(y));
                }
                else
                {
                    Model.MoveNode(View.document.GraphDocument, moving, (int)(((e.X - scrollOffset.X)) / zoomValue) - offsx, (int)(((e.Y - scrollOffset.Y)) / zoomValue) - offsy);
                }
            }
        }

        override public void ViewMouseUp(object sender, MouseEventArgs e)
        {
            try
            {
                AbstractNode an = (AbstractNode)View.document.SelectedObject;
                GraphObjectSelected(this, new FlowChartEventArgs(an, false));
            }
            catch (Exception ex)
            {
                Console.Write("taisit valita konnektorin.. Mut ei se mitään");              
            }
            

            if (moving != null)
            {
                /*if (Model.SnapToGridState.Equals(true))
                {
                    int snapX = e.X - e.X % Model.GridWidth;
                    int snapY = e.Y - e.Y % Model.GridWidth;
                    Model.MoveNode(moving, (snapX - scrollOffset.X) - offsx, (snapY - scrollOffset.Y) - offsy);
                }
                else
                {
                    Model.MoveNode(moving, (e.X - scrollOffset.X) - offsx, (e.Y - scrollOffset.Y) - offsy);
                }*/
                moving = null;
            }
        }

    }
}
